#include "LineToolBar.h"

#include <QFontDatabase>
#include <QPainter>
#include <QPainterPath>
#include <QString>
#include <QPoint>
#include <QSize>

#include <QDebug>


#include "../../rwidgets/MacroFunOfView.h"
#include "../IdRootMenu.h"
#include "../MenuIdConvert.h"
#include "../vhc/constview4color.h"
#include "../TViewDraw.h"



#include "mcore/map/MapObject.h"
#include "mcore/tools/EditWidget.h"


#include "mcore/tools/setting/IdBtnToMapTool.h"






namespace kepen {
namespace core {

LineToolBar::LineToolBar(QWidget *parent,LineEditView *eParam,const int* menu,std::size_t count)
    : QWidget{parent},editContext(eParam),m_nLengthMenu(count)
{

    std::size_t k = count*sizeof(int);
    int w,h,nWScreen,nGridWidth,nGridHeight,minWidth = 300;
    QSize rectWin = parent->size();


    isMouseLeftDown = false;
    isWindowDeactivate=false;


    nGridHeight =  Height_CELL;





    m_nIdTouchedDown = MenuId_None;
    m_nIdMouseOver = MenuId_None;
    comboBoxFlagLast = 0;



    idMenuArray = new int[count];
    cellWidthArr = new int[count];

    memcpy(idMenuArray,menu,k);

    nGridWidth = getGridWidth(count,idMenuArray, cellWidthArr);

    nWScreen = rectWin.width();
    m_nWScreen = nWScreen;

    w = nGridWidth;
    h =  nGridHeight;

    if(w> nWScreen) w = nWScreen;
    if(w<minWidth) w = minWidth;

    m_nGridWidth = w;
    m_nCellHeight = h;

    QSizePolicy sizePoFixed(QSizePolicy::Policy::Fixed, QSizePolicy::Policy::Fixed);
    sizePoFixed.setHorizontalStretch(0);
    sizePoFixed.setVerticalStretch(0);
    sizePoFixed.setHeightForWidth(false);

    setSizePolicy(sizePoFixed);
    setFixedSize(w,h);



    setMouseTracking(true);

    QObject::installEventFilter(this);

    // qDebug()  <<__FILE__ <<",Line:"<<__LINE__ << "focusPolicy:"<<focusPolicy();

}

LineToolBar::~LineToolBar()
{
    delete [] idMenuArray;
    delete [] cellWidthArr;

}

bool LineToolBar::eventFilter(QObject *watched, QEvent *event)
{
    WindowDeactivate_EventFilter_Only()
}

void LineToolBar::leaveEvent(QEvent *){
    m_nIdMouseOver = MenuId_None;
    repaint();
}

void LineToolBar::mouseMoveEvent(QMouseEvent *event){
    if(false == isMouseLeftDown){
        QPointF point = event->position();
        int nIdMouseOver = m_nIdMouseOver;
        int comboBoxFlag = 0;
        m_nIdMouseOver = getIdOfTouched(point,comboBoxFlag);
        if(nIdMouseOver != m_nIdMouseOver || comboBoxFlagLast != comboBoxFlag)
        {
            comboBoxFlagLast = comboBoxFlag;
            repaint();
        }
    }
}

void LineToolBar::mousePressEvent(QMouseEvent *event) {
    Qt::MouseButton btn = event->button();
    if(Qt::MouseButton::LeftButton == btn)
    {
        QPointF point = event->position();
        int comboBoxFlag = 0;
        ptDown = point;
        isMouseLeftDown = true;
        m_nIdTouchedDown = getIdOfTouched(point,comboBoxFlag);
        comboBoxFlagLast = comboBoxFlag;
        m_nIdMouseOver = MenuId_None;
        // editContext->repaintToolBar();
        repaint();
    }
}

void LineToolBar::mouseReleaseEvent(QMouseEvent *event) {
    int idTouched = m_nIdTouchedDown;
    bool isIgnore =(MenuId_None == idTouched) ||((IS_WhiteSpaceBar(idTouched)));
    bool _isMouseLeftDown = isMouseLeftDown;
    m_nIdTouchedDown = MenuId_None;
    m_nIdMouseOver = MenuId_None;

    isMouseLeftDown = false;

    if(_isMouseLeftDown){
        Qt::MouseButton btn = event->button();
        if (Qt::MouseButton::LeftButton == btn)
        {
            QPointF pointUp = event->position();
            QPointF  ptUp = pointUp - ptDown;

            int retFlag =0;
            int x = ptUp.x(),y = ptUp.y();
            bool isClicked = x >-DisTorClicked && x < DisTorClicked && y >-DisTorClicked && y < DisTorClicked;
            bool isGo ,isRepaintRoot;




            if(false == isIgnore && isClicked)
            {
                bool isCombox = IS_ComboBox(idTouched);
                if(isCombox)
                {
                    QPoint point;
                    int comboBoxFlag = 0;
                    idTouched = getIdOfTouched(ptDown,comboBoxFlag);
                    getBtnPosition(idTouched,point);
                    QPoint pointGlobal =  mapToGlobal(point);
                    retFlag =  editContext->onComboxClicked(idTouched,comboBoxFlag,pointGlobal);

                }else
                {
                    retFlag =  editContext->onBtnClicked(idTouched);
                }

            }
            isGo = ViewClickFlag_Go == (ViewClickFlag_Go & retFlag);
            isRepaintRoot = ViewClickFlag_RepaintRoot == (ViewClickFlag_RepaintRoot & retFlag);

            if(false == isGo && false == isRepaintRoot){
                editContext->repaintToolBar();
            }

        }
    }
}

void LineToolBar::paintEvent(QPaintEvent *)
{
    quint32 backColor = isWindowDeactivate?InDefault_Background:Default_Background;
    int widthWindow ,heightWidow;
    QPainter painter(this);
    painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform | QPainter::TextAntialiasing |QPainter::VerticalSubpixelPositioning);

    QSize rectWin = this->size();
    widthWindow  = rectWin.width();
    heightWidow = rectWin.height();

    painter.fillRect(0,0,widthWindow ,heightWidow,QColor(QRgba64::fromArgb32(backColor)));

    onPaintButtons(&painter);

    QBrush brushBorder(Qt::darkGray,Qt::SolidPattern);
    QPen penBorder(brushBorder,1.0f, Qt::SolidLine);
    painter.setPen(penBorder);
    painter.setBrush(Qt::NoBrush);
    painter.drawRect(0,0,widthWindow ,heightWidow);

    // qDebug()  <<__FILE__ <<",Line:"<<__LINE__ <<  __FUNCTION__;

}

int LineToolBar::getGridWidth(std::size_t length,const int *param, int *cellWidthArr)
{
    int widthTotal = 0;
    int  itemWidth, id;
    std::size_t i = 0, len = length;


    //
    for (; i < len; ++i) {
        id = param[i];
        if (IS_WhiteSpaceBar(id)) {
            itemWidth = WhiteSpace_M & id;

        }  else if (IS_ComboBox(id)) {
            itemWidth = Width_ComboBox;

        } else if (IS_LabelBar(id)) {

            int nFontWidth, pad = 8 ;
            QString strLabel = MenuIdConvert::GetLabelByID(id);
            QFontMetrics fontMetrics(editContext->fontLabel);
            QRect rect = fontMetrics.boundingRect(strLabel);
            nFontWidth = rect.width();
            itemWidth = nFontWidth + pad;
        }else if ( Pick_Target_Vertex == id ) {
            itemWidth = Width_CELL + 2 ;
        } else if ( ArrayAddVertexByString == id
                   || EditLayerOther == id) {
            int nFontWidth;
            QString strLabel = MenuIdConvert::GetLabelByID(id);
            QFontMetrics fontMetrics(editContext->fontLabel);
            QRect rect = fontMetrics.boundingRect(strLabel);
            nFontWidth = rect.width();
            itemWidth = nFontWidth + Width_CELL;
        }else {
            itemWidth = Width_CELL;

        }

        widthTotal += itemWidth;
        cellWidthArr[i] = itemWidth;

    }

    return widthTotal;

}

int LineToolBar::getIdOfTouched(const QPointF &point,int &comboBoxFlag)
{
    int x0 = qRound(point.x());
    int nRet = MenuId_None;

    std::size_t i, numBtns = m_nLengthMenu;
    int left, right;
    int nCellWidth;
    // int _id;
    comboBoxFlag = 0;
    right =  0;

    for (i = 0; i < numBtns; ++i) {

        left = right;
        nCellWidth = cellWidthArr[i];
        right = left + nCellWidth;
        if (x0 >= left && x0 < right) {
            nRet = idMenuArray[i];
            if(IS_ComboBox(nRet))
            {
                int dd = right - RightClick_ComboBox;
                if(x0 < dd)
                {
                    comboBoxFlag = Pos_ComboBox_Left;
                }
                else
                {
                    comboBoxFlag = Pos_ComboBox_Right;
                }

            }else
            {
                comboBoxFlag = 0;
            }
            break;
        }

    }

    return nRet;
}

void LineToolBar::onPaintButtons(QPainter *painter)
{

    int childWidth = 0,childHeight = m_nCellHeight;
    int _nID_touchedDown = m_nIdTouchedDown;
    int nIdMouseOver = m_nIdMouseOver;
    bool isEnable,isChecked,isMouseOver,isTouchedDown,isDeAct = isWindowDeactivate;
    // bool isFocused = hasFocus();
    quint32 boolFlag;
    std::size_t i, numBtns = m_nLengthMenu;
    int left, right;
    int topOfLine = 0;

    int id,sizeTextIcon = TextSize_Icon_Tool;

    int widthBmp = m_nGridWidth;
    int maxRight = qMin(m_nWScreen, widthBmp);
    const int * cellWidthPtr = cellWidthArr;
    EditViewParamTag *param = editContext->getEditViewParamRun();
    kepen::core::MapObject *mapSurface = editContext->mapSurface;
    EditWidget*ewPtr = mapSurface->getEditWidgetSingleton();


    right =  0;
    for (i = 0; i < numBtns; ++i)
    {
        id = idMenuArray[i];
        left = right;
        childWidth = cellWidthPtr[i];
        right = left + childWidth;
        if (left > maxRight || right < 0) {
            continue;
        }
        if (IS_WhiteSpaceBar(id))
            continue;

        isChecked = param->isCheckedBy(id);

        //if(PickMode_Line==id|| IdentifyMode_Point == id)isChecked = true;//test


        isEnable = param->enableBy(id);


        isMouseOver = nIdMouseOver == id;
        isTouchedDown = _nID_touchedDown == id;

        boolFlag = isChecked ? BoolFlagChecked : 0;

        if(isDeAct)boolFlag |= BoolFlagDeactivate;

        if(isEnable){
            boolFlag |= BoolFlagEnable;
            if(isMouseOver)boolFlag |= BoolFlagMouseOver;
            if(isTouchedDown)boolFlag |= BoolFlagTouched;
        }







        if(false == ((IS_WhiteSpaceBar(id)) ||  (IS_LabelBar(id)))){

            if(isChecked && false == isDeAct
                && false == isMouseOver
                && false == isTouchedDown)
            {
                QBrush _brushTogBtn(QColor(QRgba64::fromArgb32(Checked_Background)),Qt::SolidPattern);

                painter->fillRect(left, topOfLine, childWidth,childHeight,_brushTogBtn);
            }


            if (isEnable && isMouseOver
                && false == isTouchedDown){

                quint32 nBackColor =isDeAct?0xffffffffU: (isChecked ?  Checked_Background_Over : Background_BtnOver);
                QBrush brushBackOver(QColor(QRgba64::fromArgb32(nBackColor)),Qt::SolidPattern);


                painter->fillRect(left, topOfLine, childWidth,childHeight,brushBackOver);


            }

            if (isEnable && isTouchedDown){
                quint32 nBackColor = isChecked ?  Checked_Background2_Touched:Background_BtnDown;
                QBrush brushBackDown(QColor(QRgba64::fromArgb32(nBackColor)),Qt::SolidPattern);
                painter->fillRect(left, topOfLine, childWidth,childHeight,brushBackDown);

            }

        }




        if (IS_LabelBar(id)){
            if(nIdMouseOver == id && isDeAct){
                painter->fillRect(left, topOfLine, childWidth,childHeight,Qt::white);
            }
            DRAW_Text_Label(left,topOfLine,textSizeLabel,id)
        }else if(ArrayAddVertexByString == id
                   ||EditLayerOther == id)
        {
            quint32 textColor = isDeAct && (nIdMouseOver != id)  ? Color_Text_Deactivate : Color_Font_ToolBar;
            QString strLabel = MenuIdConvert::GetLabelByID(id);
            int cx0, cy0,ntLeft,ntTop,widthLabel = childWidth -Width_CELL;
            cx0 = 4+left + (widthLabel >> 1);
             cy0 = topOfLine + (childHeight >> 1);
            ntLeft = cx0 - 1000;
            ntTop = cy0 - 500;
            QRect rect4Label(ntLeft, ntTop, 2000, 1000);
            QBrush brushLabel(QColor(QRgba64::fromArgb32(textColor)),Qt::SolidPattern);
            QPen penText(brushLabel,1, Qt::SolidLine);
            painter->setFont(editContext->fontLabel);
            painter->setBrush(Qt::BrushStyle::NoBrush);
            painter->setPen(penText);
            painter->drawText(rect4Label,Qt::AlignCenter,strLabel);

            ntLeft = left +widthLabel;
            QFont &font_third = editContext->thirdFontIcon;
            uint codeText = MenuIdConvert::GetIconTextByID(id);
            int _sizeTextIcon = (EditLayerOther == id)?(-2 +sizeTextIcon):(3 +sizeTextIcon);
                QChar chTxt(codeText);
                QString szIconLabel(chTxt);
                font_third.setPointSize(_sizeTextIcon);
                cx0 = ntLeft + (Width_CELL >> 1);
                cy0 = topOfLine + (childHeight >> 1);
                ntLeft = cx0 - 1000;
                ntTop = cy0 - 500;
                if(EditLayerOther == id)ntLeft += 2;
                QRect rect4Text(ntLeft, ntTop, 2000, 1000);

                painter->setFont(font_third);
                painter->setBrush(Qt::BrushStyle::NoBrush);
                painter->setPen(penText);
                painter->drawText(rect4Text,Qt::AlignCenter,szIconLabel);

        }
        else if (DrawTool_Polygon == id) {
            int cx0, cy0;
            cx0 = left + (childWidth >> 1);
            cy0 = topOfLine + ( childHeight>> 1) +PixDIP;

            TViewDraw::DrawShapePolygon(painter,cx0,cy0,boolFlag);

        }else if (Option_MakeHole == id) {
            int cx0, cy0;
            cx0 = left + (childWidth >> 1);
            cy0 = topOfLine + ( childHeight>> 1) + PixDIP;

            TViewDraw::DrawMakeHolePolygon(painter,cx0,cy0,boolFlag);
        }else if (Pick_Target_Vertex == id) {
            TViewDraw::DrawShapePickPoint(painter,left, topOfLine, childWidth,childHeight, boolFlag);
        }else if (Pick_Target_Edge == id) {

            TViewDraw::DrawShapePickLine(painter,left, topOfLine, childWidth,childHeight, boolFlag);
        }/*else if(EditTool_Vector ==id){
            int cx0, cy0;
            float  outLine []= { 9.08f,0.41f,6.28f,1.99f,5.14f,1.99f,4.00f,2.84f,3.72f,3.98f,1.73f,6.82f,-2.25f,8.24f,
                               -6.24f,6.82f,-4.50f,5.69f,0.00f,4.50f,-9.08f,-5.98f,-9.08f,-6.54f,-8.79f,-7.40f,-8.23f,-8.24f,
                               -7.09f,-8.24f,0.02f,0.00f,1.16f,0.57f,2.58f,0.29f,3.44f,-0.57f,5.40f,-3.60f,9.08f,0.41f };
            size_t length = sizeof(outLine)/sizeof(outLine[0]);
            cx0 = left + (childWidth >> 1);
            cy0 = topOfLine + ( childHeight>> 1) +PixDIP;

            DrawShapeCoords(painter,boolFlag,cx0,cy0,length,outLine);
        }*/else if(DrawTool_RectShape == id)
        {
            int textSize = sizeTextIcon + 0;
            int _ntop = topOfLine ;
            DRAW_ICON_Font(left,_ntop,textSize,id)
        }else if(DrawTool_Circle == id
                   ||EditTool_LineSlide ==id){
            int textSize = sizeTextIcon + 3;

            DRAW_ICON_Font(left,topOfLine,textSize,id)
        }else if(ArrayAddVertexByString ==id){
            int textSize = sizeTextIcon + 4;

            DRAW_ICON_Font(left,topOfLine,textSize,id)
        }
        else if(EditTool_LineExtrude ==id){
            int cx0, cy0;
            float  outLine []= Coords_EditTool_LineExtrude;
            size_t length = sizeof(outLine)/sizeof(outLine[0]);
            cx0 = left + (childWidth >> 1);
            cy0 = topOfLine + ( childHeight>> 1) ;

            TViewDraw::DrawShapeCoords(painter,boolFlag,cx0,cy0,length,outLine);
        }else if(IS_ComboBox(id))
        {
            int bb = childWidth;
            childWidth -= WidthClick_ComboBox;
            int id_display =  param->getComboBoxDisplay(id);
            if(LocationCombox== id)
            {

            }
            else if(IdentifyPick_ByCircle == id_display )
            {

                int ntLeft,ntTop,cx0,cy0;
                cx0 = left + (childWidth >> 1);
                cy0 = topOfLine + ( childHeight>> 1) +PixDIP;

                TViewDraw::DrawShapeCircle(painter,cx0,cy0,8,boolFlag);

                childWidth = bb;
                ntLeft = left + childWidth - Width_ComboBoxFlag;
                ntTop = topOfLine + childHeight - Height_ComboBoxFlag;
                cx0 = ntLeft + (Width_ComboBoxFlag >> 1);
                cy0 = ntTop + (Height_ComboBoxFlag >> 1);
                TViewDraw::DrawComboxFlag(painter,cx0,cy0,boolFlag);
            }  else  if(IdentifyPick_ByPolygon ==id_display )
            {
                int ntLeft,ntTop,cx0,cy0;
                cx0 = left + (childWidth >> 1);
                cy0 = topOfLine + ( childHeight>> 1) - PixDIP;

                TViewDraw::DrawShapePolygonR2(painter,cx0,cy0,boolFlag);

                childWidth = bb;
                ntLeft = left + childWidth - Width_ComboBoxFlag;
                ntTop = topOfLine + childHeight - Height_ComboBoxFlag;
                cx0 = ntLeft + (Width_ComboBoxFlag >> 1);
                cy0 = ntTop + (Height_ComboBoxFlag >> 1);
                TViewDraw::DrawComboxFlag(painter,cx0,cy0,boolFlag);
            }else{
                int textSize = sizeTextIcon +2;
                int _ntop = topOfLine ;

                DRAW_ICON_Font(left,_ntop,textSize,id_display)


                    childWidth = bb;
                ntLeft = left + childWidth - Width_ComboBoxFlag;
                ntTop = topOfLine + childHeight - Height_ComboBoxFlag;
                cx0 = ntLeft + (Width_ComboBoxFlag >> 1);
                cy0 = ntTop + (Height_ComboBoxFlag >> 1);
                TViewDraw::DrawComboxFlag(painter,cx0,cy0,boolFlag);
            }





        }else if ( Option_VisibleVertexIndex == id){
            int textSize = sizeTextIcon +4;
            DRAW_ICON_Font(left,topOfLine,textSize,id)
        }else if(EditTool_Pan == id ||EditTool_Rotate == id ||EditTool_Shear ==id){
            int textSize = sizeTextIcon +2;
            int _ntop = topOfLine +PixDIP;
            DRAW_ICON_Font(left,_ntop,textSize,id)
        }else if( EditTool_Zoom ==id){
            int textSize = sizeTextIcon +1;
            DRAW_ICON_Font(left,topOfLine,textSize,id)}
        else {
            DRAW_ICON_Font(left,topOfLine,sizeTextIcon,id)
        }

        if(FileSave_BtnId == id && isEnable){
            int x0, y0,ffLeft,ffTop,ffRight,ffBottom,ffSize=4;
            QPainterPath pathRg;
            x0 = left + 10;
            y0 = topOfLine + 10;
            QBrush brushBorder(QColor(QRgba64::fromArgb32(Color_Font_ToolBar)),Qt::SolidPattern);
            QPen penEnSaved(brushBorder,1, Qt::SolidLine);
            painter->setBrush(Qt::BrushStyle::NoBrush);
            painter->setPen(penEnSaved);

            ffLeft = x0 - ffSize;
            ffTop = y0 -  ffSize;
            ffRight = x0 + ffSize;
            ffBottom = y0 + ffSize;

            pathRg.moveTo(ffLeft, y0);
            pathRg.lineTo(ffRight, y0);
            pathRg.moveTo(x0, ffTop);
            pathRg.lineTo(x0, ffBottom);

            pathRg.moveTo(ffLeft, ffTop);
            pathRg.lineTo(ffRight, ffBottom);
            pathRg.moveTo(ffLeft, ffBottom);
            pathRg.lineTo(ffRight, ffTop);

            painter->drawPath(pathRg);


        }

        if(isChecked)
            TViewDraw::DrawCheckedTriFlag(painter,left, topOfLine, childWidth,childHeight,boolFlag);

    }
}

void LineToolBar::getBtnPosition(int id, QPoint &point)
{

    std::size_t i, numBtns = m_nLengthMenu;
    int left, right;
    int nCellWidth;
    right =  0;
    for (i = 0; i < numBtns; ++i) {

        left = right;

        if(id == idMenuArray[i]){
            point.setX(left);
            point.setY(Height_CELL);

            break;
        }

        nCellWidth = cellWidthArr[i];
        right = left + nCellWidth;
    }

}


}
}
